package top.mccat.raven.combatstatus.listener;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitScheduler;
import top.mccat.raven.combatstatus.domain.CombatConfig;
import top.mccat.raven.combatstatus.utils.MsgUtils;
import top.mccat.raven.combatstatus.utils.Permision;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Distance
 * @date 2022/6/14
 */
public class FightEventListener implements Listener {
    private final Map<Player,Integer> combatStatusMap = new HashMap<>();
    private MsgUtils msgUtils;
    private CombatConfig combatConfig;
    private final Plugin plugin;
    private final BukkitScheduler scheduler = Bukkit.getScheduler();
    public FightEventListener(Plugin plugin, MsgUtils msgUtils, CombatConfig combatConfig) {
        this.msgUtils = msgUtils;
        this.combatConfig = combatConfig;
        this.plugin = plugin;
    }

    @EventHandler(priority = EventPriority.HIGH)
    public void onDamageByEntityEvent(EntityDamageByEntityEvent event){
        if(event.isCancelled()){
            return;
        }
        if(!(event.getDamager() instanceof Player)){
            return;
        }
        if(!(event.getEntity() instanceof Player)){
            return;
        }
        Player damager = (Player) event.getDamager();
        setCombatStatus(damager);
        Player defencer = (Player) event.getEntity();
        setCombatStatus(defencer);
    }

    @EventHandler(priority = EventPriority.HIGH)
    public void onFightCommandEvent(PlayerCommandPreprocessEvent event){
        if(event.isCancelled()){
            return;
        }
        Player player = event.getPlayer();
        if(player.isOp() || player.hasPermission(Permision.COMMAND_PERMISSION) || player.hasPermission(Permision.ADMIN_PERMISSION)){
            return;
        }
        if(!combatStatusMap.containsKey(player)){
            return;
        }
        msgUtils.sendToPlayer(player,"&c战斗状态中禁止使用指令！");
        event.setCancelled(true);
    }

    @EventHandler(priority = EventPriority.HIGH)
    public void onFightEntityHealthEvent(EntityRegainHealthEvent event){
        if(event.isCancelled()){
            return;
        }
        if(!(event.getEntity() instanceof Player)){
            return;
        }
        Player player = (Player) event.getEntity();
        if(player.isOp() || player.hasPermission(Permision.REPLY_PERMISSION) || player.hasPermission(Permision.ADMIN_PERMISSION)){
            return;
        }
        if(!event.getRegainReason().equals(EntityRegainHealthEvent.RegainReason.SATIATED)){
            return;
        }
        if(!combatStatusMap.containsKey(player)){
            return;
        }
        event.setCancelled(true);
    }

    /**
     * 对pvp的玩家进行战斗状态设置
     * @param player 玩家
     */
    public void setCombatStatus(Player player){
        if(player.hasPermission(Permision.REPLY_PERMISSION) || player.hasPermission(Permision.ADMIN_PERMISSION)){
            return;
        }
        if(combatStatusMap.containsKey(player)){
            combatStatusMap.put(player,combatConfig.getTime());
            return;
        }
        combatStatusMap.put(player,combatConfig.getTime());
        msgUtils.sendToPlayer(player,combatConfig.getFightMsg());
        schedulerTimer(scheduler,player);
    }

    private void schedulerTimer(BukkitScheduler scheduler, Player player){
        scheduler.runTaskLater(plugin,()->{
            if(!combatStatusMap.containsKey(player)){
                return;
            }
            int time = combatStatusMap.get(player);
            time -= 1;
            combatStatusMap.put(player,time);
            if(time < 6){
                msgUtils.sendActionBar(player,combatConfig.getPluginName()+"&a还有&c"+time+"&a秒解除");
            }
            if(time>0){
                schedulerTimer(scheduler,player);
            }else {
                msgUtils.sendToPlayer(player,combatConfig.getLeaveMsg());
                combatStatusMap.remove(player);
            }
        },20);
    }

    public void setMsgUtils(MsgUtils msgUtils) {
        this.msgUtils = msgUtils;
    }

    public void setCombatConfig(CombatConfig combatConfig) {
        this.combatConfig = combatConfig;
    }
}
